//! 中断处理

use alloc::string::String;
use core::{fmt::Display, result};

use crate::{println, processor::this_processor_id, sync::spinlock::Spinlock};

pub mod irqflags;

/// 中断错误
pub enum IrqError {
    /// 无效参数
    Invalid,
}

/// 中断结果
pub type Result<T> = result::Result<T, IrqError>;

impl Display for IrqError {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let error = match self {
            Self::Invalid => "Invalid args",
        };
        write!(f, "{}", error)
    }
}

bitflags::bitflags! {
    /// 中断触发类型
    #[derive(Clone, Copy)]
    pub struct IrqType: u32 {
        /// 无类型
        const IRQ_TYPE_NONE = 0;
        /// 上升沿触发
        const IRQ_TYPE_EDGE_RISING = 0x1;
        /// 下降沿触发
        const IRQ_TYPE_EDGE_FALLING = 0x2;
        /// 上升沿触发或者下降沿触发
        const IRQ_TYPE_EDGE_BOTH = IrqType::IRQ_TYPE_EDGE_RISING.bits()  | IrqType::IRQ_TYPE_EDGE_FALLING.bits() ;
        /// 高电平触发
        const IRQ_TYPE_LEVEL_HIGH = 0x4;
        /// 低电平触发
        const IRQ_TYPE_LEVEL_LOW = 0x8;
        /// 高低电平掩码
        const IRQ_TYPE_LEVEL_MASK = IrqType::IRQ_TYPE_LEVEL_HIGH.bits()  | IrqType::IRQ_TYPE_LEVEL_LOW.bits() ;
        /// 总掩码
        const IRQ_TYPE_MASK = IrqType::IRQ_TYPE_EDGE_BOTH.bits() | IrqType::IRQ_TYPE_LEVEL_MASK.bits();
    }
}

bitflags::bitflags! {
    /// 中断状态
    #[derive(Clone, Copy)]
    pub struct IrqState: u32 {
        /// 中断是 percpu
        const IRQ_PER_CPU = 1 << 0;
        /// 中断没有使用
        const IRQ_NOREQUEST = 1 << 1;

        /// 中断挂起
        const IRQ_PENDING = 1 << 2;
        /// 中断正在处理
        const IRQ_INPROGRESS = 1 << 3;
        /// 中断未激活
        const IRQ_MASKED = 1 << 4;
    }
}

/// 中断控制器特定的状态
#[allow(non_camel_case_types)]
pub enum IrqchipIrqState {
    /// 中断挂起?
    IRQCHIP_STATE_PENDING,
    /// 中断在处理?
    IRQCHIP_STATE_ACTIVE,
    /// 中断被禁用?
    IRQCHIP_STATE_MASKED,
    /// 中断信号高电平?
    IRQCHIP_STATE_LINE_LEVEL,
}

/// 中断描述
#[derive(Clone, Copy)]
pub struct IrqDesc {
    hwirq: u32,
    irq_type: IrqType,
    state: IrqState,
}

impl Default for IrqDesc {
    fn default() -> Self {
        Self::new()
    }
}

impl IrqDesc {
    /// 创建中断描述符
    pub const fn new() -> Self {
        Self { hwirq: 0, irq_type: IrqType::empty(), state: IrqState::empty() }
    }

    /// 硬件中断号
    #[inline(always)]
    pub fn hwirq(&self) -> u32 {
        self.hwirq
    }

    /// 中断触发类型
    #[inline(always)]
    pub fn irq_type(&self) -> &IrqType {
        &self.irq_type
    }

    /// 中断状态
    #[inline(always)]
    pub fn irq_state(&self) -> &IrqState {
        &self.state
    }
}

/// 中断控制器实现
#[allow(unused_variables)]
pub trait IrqchipImpl {
    /// 中断控制器名字
    fn name(&self) -> &str;

    /// 应答中断
    fn irq_ack(&self, desc: &IrqDesc) {}
    /// 结束中断
    fn irq_eoi(&self, desc: &IrqDesc);

    /// 禁用中断
    fn irq_disable(&self, desc: &IrqDesc);
    /// 激活中断
    fn irq_enable(&self, desc: &IrqDesc);

    /// 设置中断亲和性
    ///
    /// # Errors
    /// 中断号或者 cpumask 不正确会返回错误
    fn irq_set_affinity(&self, desc: &IrqDesc, cpumask: usize) -> Result<()>;
    /// 设置中断触发类型
    ///
    /// # Errors
    /// 中断不正确会返回错误
    fn irq_set_type(&self, desc: &IrqDesc, irq_type: IrqType) -> Result<()>;

    /// 获取中断控制器特定状态是否激活
    ///
    /// # Errors
    /// 中断不正确会返回错误
    fn irq_get_irqchip_state(&self, desc: &IrqDesc, which: &IrqchipIrqState) -> Result<bool>;
    /// 设置中断控制器特定状态
    ///
    /// # Errors
    /// 中断或者设置状态不正确会返回错误
    fn irq_set_irqchip_state(
        &self,
        desc: &IrqDesc,
        which: &IrqchipIrqState,
        state: bool,
    ) -> Result<()>;

    /// 向特定 cpu 发送 ipi 中断
    fn ipi_send_single(&self, irq: u32, cpu: usize) {
        self.ipi_send_mask(irq, 1 << cpu);
    }
    /// 向一组 cpu 发送 ipi 中断
    fn ipi_send_mask(&self, irq: u32, cpumask: usize);

    /// 中断处理
    fn irq_handle(&self);

    /// 中断控制器初始化
    fn irq_init(&self);
    /// 中断控制 cpu 初始化
    ///
    /// cpu 初始化不包括主 cpu, 因为 `irq_init` 应该顺带完成 cpu 初始化
    fn irq_init_cpu(&self, cpu: usize);
}

/// 中断管理
pub struct IrqManage<I: IrqchipImpl, const S: usize> {
    chip: I,
    v_desc: Spinlock<[IrqDesc; S]>,
}

impl<I: IrqchipImpl, const S: usize> IrqManage<I, S> {
    /// 创建中断管理器
    pub const fn new(chip: I) -> Self {
        Self { chip, v_desc: Spinlock::new([IrqDesc::new(); S]) }
    }

    /// 初始化中断管理
    pub fn init(&self) {
        self.chip.irq_init();
        let mut lock = self.v_desc.lock();
        for (i, desc) in lock.iter_mut().enumerate() {
            desc.hwirq = i as u32;
            desc.state = IrqState::IRQ_MASKED | IrqState::IRQ_NOREQUEST;
            self.chip.irq_disable(desc);
        }
    }

    /// 初始化中断控制器 cpu 接口
    pub fn init_cpu(&self) {
        self.chip.irq_init_cpu(this_processor_id());
    }

    /// 中断控制器名字
    pub fn name(&self) -> &str {
        self.chip.name()
    }

    /// 中断禁用
    pub fn irq_disable(&self, hwirq: u32) {
        let mut lock = self.v_desc.lock();
        let desc = &lock[hwirq as usize];
        self.chip.irq_disable(desc);
        lock[hwirq as usize].state.set(IrqState::IRQ_MASKED, true);
    }

    /// 中断启用
    pub fn irq_enable(&self, hwirq: u32) {
        let mut lock = self.v_desc.lock();
        let desc = &lock[hwirq as usize];
        self.chip.irq_enable(desc);
        lock[hwirq as usize].state.set(IrqState::IRQ_MASKED, false);
    }

    /// 设置中断亲和性
    ///
    /// # Errors
    /// cpumask 或者 hwirq 不正确会返回错误
    pub fn irq_set_affinity(&self, hwirq: u32, cpumask: usize) -> Result<()> {
        let lock = self.v_desc.lock();
        let desc = &lock[hwirq as usize];
        self.chip.irq_set_affinity(desc, cpumask)
    }

    /// 设置中断类型
    ///
    /// # Errors
    /// `irq_type` 或者 hwirq 不正确会返回错误
    pub fn irq_set_type(&self, hwirq: u32, irq_type: IrqType) -> Result<()> {
        let mut lock = self.v_desc.lock();
        let desc = &lock[hwirq as usize];
        self.chip.irq_set_type(desc, irq_type)?;
        lock[hwirq as usize].irq_type = irq_type;
        Ok(())
    }

    /// 获取特定于中断控制器状态
    ///
    /// # Errors
    /// which 或者 hwirq 不正确会返回错误
    pub fn irq_get_irqchip_state(&self, hwirq: u32, which: &IrqchipIrqState) -> Result<bool> {
        let lock = self.v_desc.lock();
        let desc = &lock[hwirq as usize];
        self.chip.irq_get_irqchip_state(desc, which)
    }

    /// 设置特定于中断控制器状态
    ///
    /// # Errors
    /// which 或者 hwirq 不正确会返回错误
    #[inline(always)]
    pub fn irq_set_irqchip_state(
        &self,
        hwirq: u32,
        which: &IrqchipIrqState,
        state: bool,
    ) -> Result<()> {
        let lock = self.v_desc.lock();
        let desc = &lock[hwirq as usize];
        self.chip.irq_set_irqchip_state(desc, which, state)
    }

    /// 向特定 cpu 发送 ipi
    #[inline(always)]
    pub fn send_ipi_one(&self, hwirq: u32, cpu: usize) {
        self.chip.ipi_send_single(hwirq, cpu);
    }

    /// 向 cpumask 发送 ipi
    #[inline(always)]
    pub fn send_ipi(&self, hwirq: u32, cpumask: usize) {
        self.chip.ipi_send_mask(hwirq, cpumask);
    }

    /// 处理中断控制器事件
    #[inline(always)]
    pub fn handle_irq(&self) {
        self.chip.irq_handle();
    }
}

/// 中断控制器名称
#[inline(always)]
pub fn irqchip_name() -> String {
    extern "Rust" {
        fn __irqchip_name() -> String;
    }
    unsafe { __irqchip_name() }
}

/// 中断禁用
#[inline(always)]
pub fn irq_disable(hwirq: u32) {
    extern "Rust" {
        fn __irq_disable(hwirq: u32);
    }
    unsafe { __irq_disable(hwirq) }
}

/// 中断激活
#[inline(always)]
pub fn irq_enable(hwirq: u32) {
    extern "Rust" {
        fn __irq_enable(hwirq: u32);
    }
    unsafe { __irq_enable(hwirq) }
}

/// 设置中断亲和性
///
/// # Errors
/// cpumask 或者 hwirq 不正确会返回错误
#[inline(always)]
pub fn irq_set_affinity(hwirq: u32, cpumask: usize) -> Result<()> {
    extern "Rust" {
        fn __irq_set_affinity(hwirq: u32, cpumask: usize) -> Result<()>;
    }
    unsafe { __irq_set_affinity(hwirq, cpumask) }
}

/// 设置中断类型
///
/// # Errors
/// `irq_type` 或者 hwirq 不正确会返回错误
#[inline(always)]
pub fn irq_set_type(hwirq: u32, irq_type: IrqType) -> Result<()> {
    extern "Rust" {
        fn __irq_set_type(hwirq: u32, irq_type: IrqType) -> Result<()>;
    }
    unsafe { __irq_set_type(hwirq, irq_type) }
}

/// 获取特定于中断控制器状态
///
/// # Errors
/// which 或者 hwirq 不正确会返回错误
#[inline(always)]
pub fn irq_get_irqchip_state(hwirq: u32, which: &IrqchipIrqState) -> Result<bool> {
    extern "Rust" {
        fn __irq_get_irqchip_state(hwirq: u32, which: &IrqchipIrqState) -> Result<bool>;
    }
    unsafe { __irq_get_irqchip_state(hwirq, which) }
}

/// 设置特定于中断控制器状态
///
/// # Errors
/// which 或者 hwirq 不正确会返回错误
#[inline(always)]
pub fn irq_set_irqchip_state(hwirq: u32, which: &IrqchipIrqState, state: bool) -> Result<()> {
    extern "Rust" {
        fn __irq_set_irqchip_state(hwirq: u32, which: &IrqchipIrqState, state: bool) -> Result<()>;
    }
    unsafe { __irq_set_irqchip_state(hwirq, which, state) }
}

/// 向特定 cpu 发送 ipi
#[inline(always)]
pub fn send_ipi_one(hwirq: u32, cpu: usize) {
    extern "Rust" {
        fn __send_ipi_one(hwirq: u32, cpu: usize);
    }
    unsafe {
        __send_ipi_one(hwirq, cpu);
    }
}

/// 向 cpumask 发送 ipi
#[inline(always)]
pub fn send_ipi(hwirq: u32, cpumask: usize) {
    extern "Rust" {
        fn __send_ipi(hwirq: u32, cpumask: usize);
    }
    unsafe {
        __send_ipi(hwirq, cpumask);
    }
}

// 处理中断事件
#[allow(unused)]
#[inline(always)]
pub(crate) fn handle_irqchip_irq() {
    extern "Rust" {
        fn __handle_irqchip_irq();
    }
    unsafe {
        __handle_irqchip_irq();
    }
}

// 初始化中断控制器
pub(crate) fn irq_init() {
    extern "Rust" {
        fn __irq_init();
    }
    unsafe {
        __irq_init();
    }
}

// 初始化中断控制器 cpu 接口
#[allow(unused)]
pub(crate) fn irq_init_cpu() {
    extern "Rust" {
        fn __irq_init_cpu();
    }
    unsafe {
        __irq_init_cpu();
    }
}

pub(crate) fn handle_irq(hwirq: u32) {
    println!("handle irq {}", hwirq);
}

pub(crate) fn handle_ipi(hwirq: u32) {
    println!("handle ipi {}", hwirq);
}
